package cn.ppool.test;

import cn.ppool.xmlmapper.sql.RequestSqlService;
import cn.ppool.test.utils.MapBeanUtil;
import org.hibernate.Session;
import org.hibernate.query.Query;
import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;
import java.util.Map;
import java.util.Set;


public class RequestSqlServiceImpl implements RequestSqlService {


    @Autowired
    @PersistenceContext
    protected EntityManager entityManager;

    //获取和当前线程绑定的Seesion
    public Session getSession() {
        return entityManager.unwrap(Session.class);
    }

    private void setParameter(Query query, Map<String, Object> params) {
        if (params == null || params.isEmpty()) {
            return;
        }
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            if (entry.getValue() == null) {
                query.setParameter(entry.getKey(), null);
            } else {
                Class<?> clazz = entry.getValue().getClass();
                if (clazz.getSimpleName().equals("ArrayList")) {
                    List list = (List) entry.getValue();
                    query.setParameterList(entry.getKey(), list);
                } else if (clazz.getSimpleName().equals("HashSet")) {
                    Set set = (Set) entry.getValue();
                    query.setParameterList(entry.getKey(), set);
                } else if (clazz.isArray()) {
                    Object[] o = (Object[]) entry.getValue();
                    query.setParameterList(entry.getKey(), o);
                } else {
                    query.setParameter(entry.getKey(), entry.getValue());
                }
            }
        }
    }

    @Override
    public List<Map> queryToMap(String sql, Map<String, Object> allVar, Map<String, Object> sqlVar) {
        Query query = getSession().createSQLQuery(sql);
        setParameter(query, sqlVar);
        return query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
    }

    @Override
    public <T> List<T> queryToBean(String sql, Map<String, Object> allVar, Map<String, Object> sqlVar, Class<T> clazz) {
        try {
            List<Map> mapObjList = queryToMap(sql, allVar, sqlVar);
            return MapBeanUtil.transMap2Bean(mapObjList, clazz, true);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public int requestUpdate(String sql, Map<String, Object> allVar, Map<String, Object> sqlVar) {
        Query query = getSession().createSQLQuery(sql);
        setParameter(query, sqlVar);
        return query.executeUpdate();
    }

    @Override
    public int requestDelete(String sql, Map<String, Object> allVar, Map<String, Object> sqlVar) {
        return requestUpdate(sql, allVar, sqlVar);
    }

    @Override
    public int requestInsert(String sql, Map<String, Object> allVar, Map<String, Object> sqlVar) {
        return requestUpdate(sql, allVar, sqlVar);
    }

    @Override
    public int requestUpdateEntity(Class clazz, Object entity) {
        getSession().saveOrUpdate(entity);
        return 0;
    }

    @Override
    public int requestInsertEntity(Class clazz, Object entity) {
        getSession().saveOrUpdate(entity);
        return 0;
    }

    @Override
    public int requestDeleteEntity(Class clazz, Object entity) {
        getSession().delete(entity);
        return 0;
    }

    @Override
    public void flush() {
        getSession().flush();
    }
}
